#include "arcball.hpp"
#include "matrix.cpp"
#include <iostream>
#include <cmath>

using namespace std;

arcball::arcball(vector<int> center, double radius, model *m){
	this->m = m;
	this->center = center;
	this->radius = radius;
	inMove = false;
}

arcball::~arcball(){
	m = NULL;
}

void arcball::mousePressed(int x, int y){
	if(!inMove){
		start = mouse_to_sphere(x,y);
		inMove = true;
	}
}

void arcball::mouseDragged(int x, int y){
	if(inMove){
		vector<double> move,newpos;

		//Calcul du vecteur rotation move et sauvegarde du point de départ
		newpos = mouse_to_sphere(x,y);	
		move = newpos - start;
		start = newpos;

		move *= M_PI/2;

		move.z = 0;				//pas de rotation sur l'axe z (ou y selon le repere a corriger)
		double t;

		t = move.x;
		move.x = move.y;
		move.y = t;
		Matrix<double> mat;
/*
		mat= Matrix<double>::MatrixRotateX(move.y);
		m->applyMatrix(mat);
		mat = Matrix<double>::MatrixRotateY(move.x);
		m->applyMatrix(mat);
*/


		mat = Matrix<double>::MatrixRotateEuler(move);
		m->applyMatrix(mat);
	}
}

void arcball::mouseReleased(int x, int y){
	if(inMove){
		vector<double> move = mouse_to_sphere(x,y);

		move -= start;
		move *= M_PI/2;

		double t;

		t = move.x;
		move.x = move.y;
		move.x = t;
		//move.z = 0;				//pas de rotation sur l'axe z (ou y selon le repere a corriger)
		//Matrix<double> mat = Matrix<double>::MatrixRotateEuler(move);
		//m->applyMatrix(mat);

		inMove = false;
	}
}

vector<double> arcball::mouse_to_sphere(int x, int y){	//Fonction perso
	vector<double> v;
	double t;
	v.x = x - center.x;
	v.y = y - center.y;
	v.z = 0.;

	t = radius*radius - (v.x * v.x + v.y * v.y);
	if (t>0.) {
		v.z = sqrt(t);
		v.normalize();
	}
	else {
		v.x /= radius;
		v.y /= radius;
		v.normalize();
	}
	return v;
}

vector<double> arcball::mouse_to_sphere2(int x, int y){	//Fonction choppée sur internet
	vector<double> v;
	v.x = (x - center.x) / radius;
	v.y = (y - center.y) / radius;

	double mag = v.x * v.x + v.y * v.y;
	if(mag > 1.0f) v.normalize();

	else v.z = sqrt(1.0f - mag);

	return v;
}
